import React, { useState, useEffect, useMemo } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Button, Card, Form, Radio, Input, DatePicker, Row, Col, List, Typography, Space, RadioChangeEvent, message } from 'antd';
import { connect, useIntl, history, useHistory } from 'umi';
import type { ConnectProps, Dispatch } from 'umi';
import { CardListItemDataType } from './data.d';
import type { StateType, DataType } from './model';
import styles from './index.less';
import CardMetaTitle from './components/CardMetaTitle';
import momonet from 'moment';
import { getDataSet } from './service';
import _ from 'lodash';
import cvCover from '@/assets/cv.png'
import multimodalCover from '@/assets/multimodal.png'
import nlpCover from '@/assets/nlp.png'
import recommendCover from '@/assets/recommend.png'
import speechCover from '@/assets/speech.png'
import useLocalStorage from 'react-use-localstorage';
import { useUpdateEffect } from 'ahooks';

interface DatasetProps extends ConnectProps {
  dataTypes: DataType[];
  dispatch: Dispatch;
}

export interface DatasetQueryParams {
  pageNum: number;
  pageSize: number;
  startTime?: number;
  endTime?: number;
  name?: string;
  type?: string;
  dataType?: string;
  dataTask?: string;
  annotFormat?: string;
}

const commonUrlPrefix = '/dataManage/dataSet';

const { RangePicker } = DatePicker;
const { Paragraph } = Typography;

const formItemLayout = {
  labelCol: { span: 2 },
  wrapperCol: { span: 22 },
};

const dsFormItemLayout = {
  labelCol: { span: 2, lg: 4, md: 6, sm: 8, xs: 10 },
  wrapperCol: { span: 22, lg: 20, md: 18, sm: 16, xs: 14 },
};

const allOption = { label: '全部', value: 'all' };
const cvOption = { label: '计算机视觉', value: 'cv' };

const PAGE_SIZE = 12;

const getCoverImage = (dataType: string | undefined) => {
  let image = null;

  switch (dataType) {
    case "cv":
      image = cvCover;
      break;
    case "multimodal":
      image = multimodalCover;
      break;
    case "nlp":
      image = nlpCover;
      break;
    case "recommend":
      image = recommendCover;
      break;
    case "speech":
      image = speechCover;
      break;
    default:
      break;
  }

  return image;
}

const INITAL_VALUES = {
  type: 'unstructured',
  // dataType: 'all',
  dataType: 'cv',
  dataTask: 'all',
  annotFormat: 'all',
}

const DataSet: React.FC<DatasetProps> = (props: DatasetProps) => {
  const { dataTypes: dataTypes, dispatch, location: { query } } = props;

  const [list, setList] = useState([]);
  const [curDataType, setCurDataType] = useState<DataType>({ label: '计算机视觉', value: 'cv' });
  const [curDataTask, setCurDataTask] = useState<DataType>({ label: '全部', value: 'all' });
  const [curAnnotFormat, setCurAnnotFormat] = useState<DataType>({ label: '全部', value: 'all' });
  const [dataTasks, setDataTasks] = useState<DataType[]>([]);
  const [annotFormats, setAnnotFormats] = useState<DataType[]>([]);
  const [pagination, setPagination] = useState({ pageNum: 1, pageSize: PAGE_SIZE });
  const [loading, setLoading] = useState<boolean>(false);
  const [total, setTotal] = useState<number>(0);
  const [filters, setFilters] = useLocalStorage('dataset-filters', '');
  const [initialValues, setInitialValues] = useState(() => {
    if (query && query['fromDetail'] === 'true') {
      return JSON.parse(filters) || INITAL_VALUES;
    } else {
      return INITAL_VALUES;
    }
  });

  const [form] = Form.useForm();

  const getDatasets = async (params: DatasetQueryParams) => {
    setLoading(true);

    const { code, data, msg } = await getDataSet(params) || {};

    setLoading(false);

    if (code === 0) {
      setList(data.items);
      setTotal(data.total);
    } else {
      message.error(`查询失败：${msg}`);
    }
  }

  useEffect(() => {
    if (!dataTypes.length) {
      dispatch({ type: 'dataSet/getDataType' });
    }
  }, []);

  useEffect(() => {
    if (dataTypes.length > 0) {
      const type = dataTypes.find(t => t.value === curDataType.value);
      if (type?.children) {
        setDataTasks(type.children);
      }
    }
  }, [dataTypes]);

  useEffect(() => {
    if (query && query['fromDetail'] === 'true') {
      setInitialValues(JSON.parse(filters));
    }
  }, [query]);

  // useEffect(() => {
  //   let allDataTask: DataType[] = [];

  //   dataTypes.forEach(type => {
  //     allDataTask = [...allDataTask, ...type?.children || []];
  //   });

  //   setDataTasks(allDataTask);
  // }, [dataTypes]);

  useEffect(() => {
    let allAnnotFormats: DataType[] = [];

    dataTasks.forEach(task => {
      allAnnotFormats = [...allAnnotFormats, ...task?.children || []];
    });
    // 去重
    setAnnotFormats(_.uniqWith(allAnnotFormats, _.isEqual));
  }, [dataTasks]);


  useEffect(() => {
    let allDataTask: DataType[] = [];

    if (curDataType.value === 'all') {
      dataTypes.forEach(type => {
        allDataTask = [...allDataTask, ...type?.children || []];
      });

      setDataTasks(allDataTask);

    } else {
      // 获取当前数据任务，用于获取默认cv数据集children
      const currentDataType = dataTypes.find(type => type.value === curDataType.value);
      setDataTasks(curDataType.children || currentDataType?.children || []);
    }
    // reset dataTask to all
    form.setFieldsValue({ dataTask: initialValues.dataTask });
    setCurDataTask(allOption);
  }, [curDataType]);

  useEffect(() => {
    let allFormats: DataType[] = [];

    if (curDataTask.value === 'all') {
      dataTasks.forEach(task => {
        allFormats = [...allFormats, ...task?.children || []];
      });

      // 去重
      setAnnotFormats(_.uniqWith(allFormats, _.isEqual));
    } else {
      setAnnotFormats(curDataTask.children || []);
    }
    // reset curAnnotFormat to all
    form.setFieldsValue({ annotFormat: initialValues.annotFormat });
    setCurAnnotFormat(allOption);
  }, [curDataTask]);

  useEffect(() => {
    const values = form.getFieldsValue();
    queryDatasetsByValues(values);
  }, [pagination]);

  useUpdateEffect(() => {
    const values = form.getFieldsValue();
    queryDatasetsByValues(values);
  }, [curDataType, curDataTask, curAnnotFormat]);

  const { formatMessage: f } = useIntl();

  const queryDatasetsByValues = (values: any) => {
    let queries: DatasetQueryParams = { pageNum: pagination.pageNum, pageSize: pagination.pageSize };

    const { name, type, createTime, dataType, dataTask, annotFormat } = values;

    name && (queries['name'] = name);
    type && (queries['type'] = type);
    dataType && dataType !== 'all' && (queries['dataType'] = dataType);
    dataTask && dataTask !== 'all' && (queries['dataTask'] = dataTask);
    annotFormat && annotFormat !== 'all' && (queries['annotFormat'] = annotFormat);

    if (createTime) {
      queries['startTime'] = createTime[0].valueOf();
      queries['endTime'] = createTime[1].valueOf();
    }

    getDatasets(queries);
  }

  const onFinish = (values: any) => {
    // console.log('Received values of form: ', values);
    queryDatasetsByValues(values);
  };

  const onChangeDataType = (e: RadioChangeEvent) => {
    const dataTypeWrapper = dataTypes.find(t => t.value === e.target.value);
    setCurDataType(dataTypeWrapper || allOption);
  }

  const onChangeDataTask = (e: RadioChangeEvent) => {
    const dataTaskWrapper = dataTasks.find(t => t.value === e.target.value);
    setCurDataTask(dataTaskWrapper || allOption);
  }

  const onChangeAnnotFormat = (e: RadioChangeEvent) => {
    const annotFormatsWrapper = annotFormats.find(t => t.value === e.target.value);
    setCurAnnotFormat(annotFormatsWrapper || allOption);
  }

  const onReset = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
    form.resetFields();
    setCurDataType(cvOption);
    setCurDataTask(allOption);
    setCurAnnotFormat(allOption);
  }

  const toDetails = (id: string | number) => {
    const filters = {
      type: 'unstructured',
      dataType: curDataType.value,
      dataTask: curDataTask.value,
      annotFormat: curAnnotFormat.value,
    }
    setFilters(JSON.stringify(filters));

    history.push(`/dataManage/dataSet/detail/${id}`);
  }

  return (
    <PageHeaderWrapper>
      <div className={styles.datasetListWrap}>
        <Card bordered={false}>
          <div className={styles.createWrapper}>
            <Button
              type='primary'
              onClick={() => history.push(`${commonUrlPrefix}/add`)}
            >{f({ id: 'dataSet.list.create' })}</Button>
          </div>
          <div className={styles.conditionWrapper}>
            <Form
              name="dataset_query"
              {...formItemLayout}
              onFinish={onFinish}
              initialValues={{ ...initialValues }}
              form={form}
            >
              <Row>
                <Col span={12}>
                  <Form.Item
                    name="name"
                    label="数据集名称"
                    {...dsFormItemLayout}
                  >
                    <Input style={{ width: 295 }} placeholder='请输入名称' />
                  </Form.Item>
                </Col>
                <Col span={12}>
                  <Form.Item
                    name="createTime"
                    label="创建时间"
                    {...dsFormItemLayout}
                  >
                    <RangePicker />
                  </Form.Item>
                </Col>
              </Row>
              {/* <Row>
                <Col span={24}>
                  <Form.Item
                    name="type"
                    label="数据集类型"
                  >
                    <Radio.Group>
                      <Radio.Button value="unstructured">非结构化</Radio.Button>
                      <Radio.Button value="structured">结构化</Radio.Button>
                    </Radio.Group>
                  </Form.Item>
                </Col>
              </Row> */}
              {/* <Form.Item
                name="dataType"
                label="数据类型"
              >
                <Radio.Group onChange={onChangeDataType} value={initialValues.dataType}>
                  {
                    [allOption, ...dataTypes].map(type => (
                      <Radio.Button key={type.value} value={type.value}>{type.label}</Radio.Button>
                    ))
                  }
                </Radio.Group>
              </Form.Item> */}
              <Form.Item
                name="dataTask"
                label="数据任务"
              >
                <Radio.Group onChange={onChangeDataTask} value={initialValues.dataTask}>
                  {
                    [allOption, ...dataTasks].map(type => (
                      <Radio.Button key={type.value} value={type.value} >{type.label}</Radio.Button>
                    ))
                  }
                </Radio.Group>
              </Form.Item>
              <Form.Item
                name="annotFormat"
                label="标注格式"
              >
                <Radio.Group value={initialValues.annotFormat} onChange={onChangeAnnotFormat}>
                  {
                    [allOption, ...annotFormats].map(type => (
                      <Radio.Button key={type.value} value={type.value} >{type.label}</Radio.Button>
                    ))
                  }
                </Radio.Group>
              </Form.Item>
              <div className={styles.bottomButtonsWrapper}>
                <Row>
                  <Col span={2} offset={22} xl={{ span: 3, offset: 21 }}>
                    <Space size='small'>
                      <Form.Item>
                        <Button htmlType="button" onClick={onReset}>
                          重置
                        </Button>
                      </Form.Item>
                      <Form.Item>
                        <Button type="primary" htmlType="submit">
                          查询
                        </Button>
                      </Form.Item>
                    </Space>
                  </Col>
                </Row>
              </div>
            </Form>
          </div>
        </Card>
      </div>
      <div className={styles.cardList}>
        <List<Partial<CardListItemDataType>>
          rowKey="id"
          loading={loading}
          grid={{
            gutter: 16,
            xs: 1,
            sm: 2,
            md: 3,
            lg: 3,
            xl: 4,
            xxl: 6,
          }}
          pagination={{
            onChange: (page: number, pageSize?: number) => {
              setPagination({ pageNum: page, pageSize: pageSize || PAGE_SIZE });
            },
            pageSize: PAGE_SIZE,
            total,
            showSizeChanger: false,
            showQuickJumper: true,
          }}
          dataSource={list}
          renderItem={(item) => {
            if (item && item.id) {
              return (
                <List.Item key={item.id}>
                  <Card
                    title={<a>{item.name}</a>}
                    hoverable
                    className={styles.card}
                    cover={<img alt="" className={styles.cardCover} src={item.bgImgUrl || getCoverImage(item.dataType)} />}
                    onClick={() => toDetails(item.id)}
                  >
                    <Card.Meta
                      title={<CardMetaTitle dataType={item?.dataType || ''} dataTask={item?.dataTask || ''} dsVersion={item?.lastedVersion || ''} />}
                      description={
                        <Paragraph className={styles.item} ellipsis={{ rows: 3 }}>
                          {item.description}
                        </Paragraph>
                      }
                    />
                  </Card>
                </List.Item>
              );
            }
          }}
        />
      </div>
    </PageHeaderWrapper>
  )
}

export default connect(({ dataSet: { dataTypes } }: { dataSet: StateType }) => ({
  dataTypes,
}))(DataSet);